/*
 * $Id$
 *
 * Copyright ( c ) 2014 TH Supcom Corporation. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of TH Supcom
 * Corporation ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with TH Supcom Corporation or a TH Supcom
 * authorized reseller (the "License Agreement"). TH Supcom may make changes to the
 * Confidential Information from time to time. Such Confidential Information may
 * contain errors.
 *
 * EXCEPT AS EXPLICITLY SET FORTH IN THE LICENSE AGREEMENT, TH Supcom DISCLAIMS ALL
 * WARRANTIES, COVENANTS, REPRESENTATIONS, INDEMNITIES, AND GUARANTEES WITH
 * RESPECT TO SOFTWARE AND DOCUMENTATION, WHETHER EXPRESS OR IMPLIED, WRITTEN OR
 * ORAL, STATUTORY OR OTHERWISE INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A
 * PARTICULAR PURPOSE. TH Supcom DOES NOT WARRANT THAT END USER'S USE OF THE
 * SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR SECURE.
 *
 * TH Supcom SHALL NOT BE LIABLE TO END USER, OR ANY OTHER PERSON, CORPORATION OR
 * ENTITY FOR INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL
 * DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR USE, WHETHER IN AN
 * ACTION IN CONTRACT, TORT OR OTHERWISE, EVEN IF TH Supcom HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES. TH Supcom' TOTAL LIABILITY TO END USER SHALL NOT
 * EXCEED THE AMOUNTS PAID FOR THE TH Supcom SOFTWARE BY END USER DURING THE PRIOR
 * TWELVE (12) MONTHS FROM THE DATE IN WHICH THE CLAIM AROSE.  BECAUSE SOME
 * STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL
 * OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO END USER.
 *
 * Copyright version 2.0
 */
package com.th.supcom.pds.impl.service.internal.phamapply;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import net.carefx.fc.framework.web.gwt.util.FcUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.th.supcom.pds.domain.pojo.InpPhamApplyDetailSummary;
import com.th.supcom.pds.domain.pojo.InpPhamApplyPatInfo;
import com.th.supcom.pds.domain.vo.InpPhamApplyDetailVO;
import com.th.supcom.pds.impl.common.enums.AvailableEnum;
import com.th.supcom.pds.impl.common.enums.NeedDispenseEnum;
import com.th.supcom.pds.impl.common.enums.NoDispenseReason;
import com.th.supcom.pds.impl.common.enums.StockEnoughEnum;

/**
 *
 */
public final class PhamApplyStaticMethod
{
    /** 日志记录器. */
    public static final Logger s_logger = LoggerFactory.getLogger (PhamApplyStaticMethod.class);

    private PhamApplyStaticMethod ()
    {

    }

    /**
     * 更新患者是否摆药
     */
    public static void updateApplyDispenseFlag (List <InpPhamApplyPatInfo> currentPatInfos, List <InpPhamApplyDetailVO> detailVOList)
    {
        Map <Long, InpPhamApplyPatInfo> patInfoMap = PhamApplyConvertUtils.convertPatInfoListToMapByPaivisitId (currentPatInfos);
        for (InpPhamApplyDetailVO vo : detailVOList)
        {
            InpPhamApplyPatInfo patInfo = patInfoMap.get (vo.getPaiVisitId ());
            vo.setMandatoryDispenseFlag (patInfo.getArreageDispense ());
            // 如果是剩余数量足够了不摆药则不摆药
            if (NoDispenseReason.LEFT_ENOUGH.getEnumName ().equals (vo.getNoDispenseMemo ()))
            {
                continue;
            }
            // 如果不可供则不摆药
            if (AvailableEnum.NO.getEnumCode ().equals (vo.getApplySupplyFlag ()))
            {
                vo.setDispenseResultFlag (NeedDispenseEnum.NO.getEnumCode ());
                continue;
            }

            // 如果欠费摆药，则直接进行摆药
            if (AvailableEnum.YES.getEnumCode ().equals (patInfo.getArreageDispense ()))
            {
                vo.setDispenseResultFlag (AvailableEnum.YES.getEnumCode ());
                continue;
            }

            if (vo.getArreas ())
            {
                vo.setDispenseResultFlag (AvailableEnum.NO.getEnumCode ());
            }
            else
            {
                vo.setDispenseResultFlag (AvailableEnum.YES.getEnumCode ());
            }
        }
    }

    /**
     * 更新请领明细药品的库存状态
     * 
     * @param detailList
     * @param summaryList
     */
    public static void updateApplyStockStatus (List <InpPhamApplyDetailVO> detailList, List <InpPhamApplyDetailSummary> summaryList)
    {
        Map <String, InpPhamApplyDetailSummary> summaryMap = PhamApplyConvertUtils.convertPhamInfoListToMapByPhamStdCode (summaryList);

        // 计算药品总剂量
        Map <String, Double> dosageMap = new HashMap <String, Double> ();

        for (InpPhamApplyDetailVO vo : detailList)
        {
            if (dosageMap.containsKey (vo.getPhamStdCode ()))
            {
                Double dosageSum = dosageMap.get (vo.getPhamStdCode ());
                dosageSum += vo.getDosageSum ();
                dosageMap.put (vo.getPhamStdCode (), dosageSum);
            }
            else
            {
                dosageMap.put (vo.getPhamStdCode (), vo.getDosageSum ());
            }
        }

        // 记录库存是否充足
        for (InpPhamApplyDetailVO vo : detailList)
        {
            InpPhamApplyDetailSummary summary = summaryMap.get (vo.getPhamStdCode ());
            vo.setApplySupplyFlag (summary.getApplySupplyFlag ());

            if (null == summary.getStockAmount () || summary.getStockAmount () < dosageMap.get (vo.getPhamStdCode ()))
            {
                vo.setStockEnoughFlag (StockEnoughEnum.NO.getEnumCode ());
            }
            else
            {
                vo.setStockEnoughFlag (StockEnoughEnum.YES.getEnumCode ());
            }
        }
    }

    /**
     * 更新请领明细药品的库存状态
     * 
     * @param detailList
     * @param summaryList
     */
    public static void updateDispenseStockStatus (List <InpPhamApplyDetailVO> detailList, List <InpPhamApplyDetailSummary> summaryList)
    {
        Map <String, InpPhamApplyDetailSummary> summaryMap = PhamApplyConvertUtils.convertPhamInfoListToMapByPhamStdCode (summaryList);
        // 计算药品总剂量
        Map <String, Double> dosageMap = new HashMap <String, Double> ();

        for (InpPhamApplyDetailVO vo : detailList)
        {
            // 此处用List是为了能够重用请领时的方法
            List <InpPhamApplyDetailVO> tempList = new ArrayList <InpPhamApplyDetailVO> ();
            tempList.add (vo);
            InpPhamApplyDetailSummary summary = summaryMap.get (vo.getPhamStdCode ());
            if (null == summary)
            {
                continue;
            }

            if (dosageMap.containsKey (vo.getPhamStdCode ()))
            {
                Double dosageSum = dosageMap.get (vo.getPhamStdCode ());
                dosageSum += vo.getFactor () * vo.getApplyAmount ();
                dosageMap.put (vo.getPhamStdCode (), dosageSum);
            }
            else
            {
                Double dosageSum = 0D + vo.getFactor () * vo.getApplyAmount ();
                dosageMap.put (vo.getPhamStdCode (), dosageSum);
            }
        }

        // 记录库存是否充足
        for (InpPhamApplyDetailVO vo : detailList)
        {
            InpPhamApplyDetailSummary summary = summaryMap.get (vo.getPhamStdCode ());
            if (null == summary)
            {
                continue;
            }
            vo.setAllocation (summary.getAllocation ());
            vo.setApplySupplyFlag (summary.getApplySupplyFlag ());

            if (null == summary.getStockAmount () || summary.getStockAmount () < dosageMap.get (vo.getPhamStdCode ()))
            {
                vo.setStockEnoughFlag (StockEnoughEnum.NO.getEnumCode ());
                vo.setNoDispenseMemo (NoDispenseReason.LACK_STOCK.getEnumName ());
            }
            else
            {
                vo.setStockEnoughFlag (StockEnoughEnum.YES.getEnumCode ());
            }
        }
    }

    /**
     * 根据医嘱子序号合并
     * 
     * @param inpPhamApplyDetails
     * @return
     */
    public static List <InpPhamApplyDetailVO> combineDetailByOrderSubNo (List <InpPhamApplyDetailVO> inpPhamApplyDetails)
    {
        Set <String> set = new HashSet <String> ();
        List <InpPhamApplyDetailVO> result = new ArrayList <InpPhamApplyDetailVO> ();
        for (InpPhamApplyDetailVO inpPhamApplyDetailVO : inpPhamApplyDetails)
        {
            String key = inpPhamApplyDetailVO.getPaiVisitId () + inpPhamApplyDetailVO.getOrderNo () + inpPhamApplyDetailVO.getOrderSubNo ()
                         + inpPhamApplyDetailVO.getPhamStdCode ();
            if (!set.contains (key))
            {
                result.add (inpPhamApplyDetailVO);
                set.add (key);
            }
        }
        return result;
    }

    /**
     * 获取库存信息
     * 
     * @param list
     */
    public static void getInpApplyPhamStockInfo (List <InpPhamApplyDetailSummary> summaryList, List <InpPhamApplyDetailSummary> phamStockList)
    {
        if (CollectionUtils.isEmpty (phamStockList))
        {
            return;
        }

        Map <String, InpPhamApplyDetailSummary> map = PhamApplyConvertUtils.convertPhamInfoListToMapByPhamStdCode (phamStockList);
        for (InpPhamApplyDetailSummary inpPhamApplyDetailSummary : summaryList)
        {
            if (map.containsKey (inpPhamApplyDetailSummary.getPhamStdCode ()))
            {
                InpPhamApplyDetailSummary phamStockInfo = map.get (inpPhamApplyDetailSummary.getPhamStdCode ());
                inpPhamApplyDetailSummary.setStockAmount (phamStockInfo.getStockAmount ());
            }
        }
    }

    /**
     * 
     * @param seqNo
     * @param applicant
     * @return
     */
    public static String generateApplyNo (Long seqNo, String applicant)
    {
        StringBuilder applyNo = new StringBuilder ();
        Date now = FcUtils.getCurrentServerDateTimeForServer ();
        DateFormat daf = new SimpleDateFormat ("yyyyMMdd", Locale.CHINA);
        applyNo.append (daf.format (now));
        if (null != applicant)
        {
            applyNo.append (applicant);
        }
        DecimalFormat def = new DecimalFormat ("0000");
        if (null != seqNo)
        {
            applyNo.append (def.format (seqNo));
        }
        return applyNo.toString ();
    }

    /** 公司版权信息. */
    public static final String copyright = "Copyright 2014, XuNuo Corporation";

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";
}
